#include "AutogenCodeGenerator.h"
#include "CppInfo.h"
#include "DefineCommon.h"
#include "EString.h"
// #include <QtCore/QFile>
#include <iostream>
#include <fstream>

void AutogenCodeGenerator_pickLoopStr(size_t posStart, const EString& str, size_t& pos1, size_t& len, EString& result)
{
    size_t pos2 = 0;
    len = 0;
    
    pos1 = str.find("#LOOPSTA#", posStart);
    if (pos1 == -1) return;

    pos2 = str.find("#LOOPEND#", pos1);
    if (pos2 == -1) return;

    len = pos2 - pos1 + 9;

    result = str.subStr(pos1, len);

    result.replace("#LOOPSTA#", "");
    result.replace("#LOOPEND#", "");
}

AutogenCodeGenerator::AutogenCodeGenerator()
{
    this->fillTemplateStr_cpp();
    this->fillTemplateStr_h();
}

AutogenCodeGenerator::~AutogenCodeGenerator()
{
}

void AutogenCodeGenerator::collectionToFiles(CppInfo::CppCollectionPtr collPtr, const EString& dirName)
{
    /**generate wrap class defines*/
    EList<CppInfo::ClassPtr> wrapCList;
    
    //loop collPtr an check if class is needed, then add parent class info, and add class to wrapCList
    for(EMap<EString, CppInfo::ClassPtr>::iterator it = collPtr->mapClassPtr.begin();
            it != collPtr->mapClassPtr.end();
            it++)
    {
        if(EString::EStringListContains(collPtr->needClassNameList, it->first) == false)
        {
            continue;
        }

        CppInfo::ClassPtr c = it->second;

        //fill groupName
        for (int i=0; i<c->variableList.size(); i++) 
        {
            c->variableList[i]->userData = c->name;
        }

        for (int i=0; i<c->functionList.size(); i++) 
        {
            c->functionList[i]->userData = c->name;
        }
    //
        EStringList parentNameList;
        for(int i =0 ; i < c->parentNameList.size(); i++)
        {
            // if(collPtr->mapClassPtr.contains(c->parentNameList[i]))
            if(collPtr->mapClassPtr.find(c->parentNameList[i]) != collPtr->mapClassPtr.end())
            {
                parentNameList.push_back(c->parentNameList[i]);
                //copy parent's vars and funs to this class
                CppInfo::ClassPtr parent = collPtr->mapClassPtr[c->parentNameList[i]];
                this->copyParentClassToClass(parent, c);
                //TODO:? 
                //Is it possible that up two lines are droped because:
                //When a parent EItem class is also compiled with autgen code,
                //then child EItem class is constructed and parent is constructed implict.
                //And it is the same EItemMetae for child and parent
            }
        }

        c->parentNameList = parentNameList;

        CppInfo::ClassPtr newC = this->classToWrapClass(c);

        wrapCList.push_back(newC);
    }

    for(int i = 0; i < wrapCList.size(); i++)
    {
        EString fileName = wrapCList[i]->name;

        EString fileNameCpp = fileName + "_autogen.cpp";
        this->classToFile_cpp(wrapCList[i], dirName+"/"+fileNameCpp);

        EString fileNameH = fileName + "_autogen.h";
        this->classToFile_h(wrapCList[i], dirName+"/"+fileNameH);
    }
}



CppInfo::ClassPtr AutogenCodeGenerator::classToWrapClass(CppInfo::ClassPtr oldC  )
{
    CppInfo::ClassPtr newC(new CppInfo::Class);

    newC->name = oldC->name;
    newC->description = oldC->description;
    newC->parentNameList = oldC->parentNameList;
    newC->constructorList = oldC->constructorList;
    newC->destructorList = oldC->destructorList;
    newC->ifPureVirtual = oldC->ifPureVirtual; 
    newC->userData = oldC->userData;

    for(int i = 0; i < oldC->functionList.size(); i++)
    {
        CppInfo::FunctionPtr fun = oldC->functionList[i];
        if(fun->name.left(3) == "ui_"
            || fun->name.left(6) == "OnSet_"
            || fun->name.left(6) == "OnGet_")
        {
            newC->functionList.push_back(fun);
        }
    }

    for(int i = 0; i < oldC->variableList.size(); i++)
    {
        CppInfo::VariablePtr var = oldC->variableList[i];
        if(var->name.left(3) == "ui_" 
            )
        {
            newC->variableList.push_back(var);
        }
    }

    // EList<EnumPtr> enumList;

    return newC;
}

void AutogenCodeGenerator::copyParentClassToClass(CppInfo::ClassPtr parent, CppInfo::ClassPtr c)
{

    for(int i = parent->variableList.size()-1 ; i >=0 ; i--)
    {
        // if(i < 0)
            // break;
        // ELOG_DEBUG("i=%d", i);
        // c->variableList.push_back(parent->variableList[i]);
        
        //userData is used to represent group name 
        parent->variableList[i]->userData = parent->name;

        c->variableList.insert(
                c->variableList.begin(),
                parent->variableList[i]
                );
    }

    for(int i = parent->functionList.size()-1 ; i >=0 ; i--)
    {
        // c->functionList.push_back(parent->functionList[i]);
        parent->functionList[i]->userData = parent->name;

        c->functionList.insert(
                c->functionList.begin(),
                parent->functionList[i]
                );
    }
}

void AutogenCodeGenerator::classToFile_cpp(CppInfo::ClassPtr c, const EString& fileName)
{
    std::ofstream file(fileName.data());
    if (!file)
    {
        ELOG_ERROR("Failed to open file %s", fileName.data());
        return;
    }

    // EString content = this->m_templateStr;
    // EString content = classPtr->getPrintStr();
    EString content;
    // content += classPtr->getPrintStr();
    this->addWrapClassPrintInfoStr(c, content);

    this->replaceTemplateInclude(this->m_templateInclude, c, content);

    //loop member functions for "EItemInPlugin_MemberFun_ui_testAdd"
    for (int i = 0; i < c->functionList.size(); i++)
    {
        CppInfo::FunctionPtr fun = c->functionList[i];
        if (fun->name.left(3) != "ui_")
        {
            continue;
        }
        this->replaceTemplateMemberFun(this->m_templateMemberFunction, c, fun, content);
    }

    //loop member var for "EItemInPlugin_OnSet_ui_testDouble"
    for (int i = 0; i < c->variableList.size(); i++)
    {
        CppInfo::VariablePtr var = c->variableList[i];

        //if there are no one OnSet function of this var, then skip;
        EString tempFunName = EString("OnSet_") + var->name;
        //search functionlist to find tempFunName
        bool ifHasOnSetFunction = false;
        for (int i = 0; i < c->functionList.size(); i++)
        {
            CppInfo::FunctionPtr fun = c->functionList[i];
            if (fun->name == tempFunName)
            {
                ifHasOnSetFunction = true;
                break;
            }
        }

        if(ifHasOnSetFunction)
        {
            this->replaceTemplateMemberVar(
                    this->m_templateMemberValueSetFun
                    , c
                    , var
                    , content
                    );
        }
        else
        {
            this->replaceTemplateMemberVar(
                    this->m_templateMemberValueSetFun_default
                    , c
                    , var
                    , content
                    );
        }

        
        tempFunName = EString("OnGet_") + var->name;
        bool ifHasOnGetFunction = false;
        for (int i = 0; i < c->functionList.size(); i++)
        {
            CppInfo::FunctionPtr fun = c->functionList[i];
            if (fun->name == tempFunName)
            {
                ifHasOnGetFunction = true;
                break;
            }
        }
        
        if(ifHasOnGetFunction)
        {
            this->replaceTemplateMemberVar(
                    this->m_templateMemberValueGetFun
                    , c
                    , var
                    , content);
        }
        else 
        {
            this->replaceTemplateMemberVar(
                    this->m_templateMemberValueGetFun_default
                    , c
                    , var
                    , content);
        }
    }
    

    this->replaceTemplateCreateMetaFunction(this->m_templateCreateMetaFunction, c, content);
    this->replaceTemplateConstructFunction(this->m_templateConstructFunction, c, content);
    this->replaceTemplateFactoryFunction(this->m_templateFactoryFunction, c, content);
    this->replaceTemplateRegistPluginFunction(this->m_templateRegistPluginFunction, c, content);

    file << content.data() << std::endl;

    file.close();
}

void AutogenCodeGenerator::addWrapClassPrintInfoStr(CppInfo::ClassPtr c, EString& content)
{
    EString temp = c->getPrintStr();
    temp.insert(0, "//");
    temp.replace("\n", "\n//");

    content += temp;
}

void AutogenCodeGenerator::replaceTemplateInclude(const EString& templateStr, CppInfo::ClassPtr c, EString& content)
{
    EString temp = templateStr;
    temp.replace("#EItemName#", c->name.data());
    content += temp;
}

void AutogenCodeGenerator::replaceTemplateMemberFun(const EString& templateStr, CppInfo::ClassPtr c, CppInfo::FunctionPtr fun, EString& content)
{
        EString temp = templateStr;

        //replace class name and function name
        temp.replace("#EItemName#", c->name.data());
        temp.replace("#MemberFunName#", fun->name.data());
        temp.replace("#MemberFunReturnType#", fun->returnType.data());
        temp.replace("#MemberFunGroupName#", fun->userData.data());

        size_t pos1 = 0;
        size_t pos2 = 0;
        size_t len = 0;
        while (pos1 != -1 && pos2 != -1)
        {
            size_t posStart = 0;

            pos1 = temp.find("#LOOPSTA#", posStart);
            if (pos1 == -1) break;
            pos2 = temp.find("#LOOPEND#", pos1);
            if (pos2 == -1) break;

            len = pos2 - pos1 + 9;

            EString loopStr = temp.subStr(pos1, len);
            loopStr.replace("#LOOPSTA#", "");
            loopStr.replace("#LOOPEND#", "");

            EString loopStrSum;
            for (int j = 0; j < fun->parameterList.size(); j++)
            {
                EString loopStrTemp = loopStr;

                loopStrTemp.replace("#i#", EString::number(j).data());
                loopStrTemp.replace("#parameterType#", fun->parameterList[j]->typeName.data());
                loopStrTemp.replace("#parameterName#", fun->parameterList[j]->name.data());

                /*if (loopStrTemp.right(1) == ";")
                {
                    loopStrTemp += "\n";
                }
                else */
                if (loopStrTemp.right(1) == ",")
                {
                    if ((j < fun->parameterList.size() - 1))
                    {
                        loopStrTemp += "\n";
                    }
                    else
                    {
                        loopStrTemp.removeRight(1);
                        loopStrTemp += "\n";
                    }
                        
                }
                    
                loopStrSum += loopStrTemp;
            }
            temp.replace(pos1, len, loopStrSum.data());
        }

        content += temp;
}

void AutogenCodeGenerator::replaceTemplateMemberVar(const EString& templateStr, CppInfo::ClassPtr c, CppInfo::VariablePtr var, EString& content)
{
    EString temp = templateStr;

    //replace class name and function name
    temp.replace("#EItemName#", c->name.data());
    temp.replace("#MemberVarName#", var->name.data());
    temp.replace("#MemberVarType#", var->typeName.data());
    temp.replace("#MemberVarGroupName#", var->userData.data());

    //#EItemName#_OnSet_#MemberVarName#
    EString tempFunName = EString("OnSet_") + var->name;
    //search functionlist to find tempFunName
   /* bool tempIfFound=false;
    for (int i = 0; i < c->functionList.size(); i++)
    {
        CppInfo::FunctionPtr fun = c->functionList[i];
        if (fun->name == tempFunName)
        {
            tempIfFound = true;
            break;
        }
    }
    if (tempIfFound == false)
    {
        temp.replace(
                (c->name+"_OnSet_"+ var->name).data(), 
                "nullptr");
    }*/

    //#EItemName#_OnGet_#MemberVarName#
    /*tempFunName = EString("OnGet_") + var->name;
    tempIfFound=false;
    for (int i = 0; i < c->functionList.size(); i++)
    {
        CppInfo::FunctionPtr fun = c->functionList[i];
        if (fun->name == tempFunName)
        {
            tempIfFound = true;
            break;
        }
    }
    if (tempIfFound == false)
    {
        temp.replace(
                (c->name + "_OnGet_" + var->name).data(),
                "nullptr");
    }*/

    content += temp;
}

void AutogenCodeGenerator::replaceTemplateCreateMetaFunction(const EString& templateStr, CppInfo::ClassPtr c, EString& content)
{
    EString temp = templateStr;
    temp.replace("#EItemName#", c->name.data());
    temp.replace("#EItemDescription#", c->description.data());

    {
        //handle member functions
    
        size_t pos1 = 0;
        size_t pos2 = 0;
        size_t len = 0;
        size_t posStart = 0;

        pos1 = temp.find("#LOOPSTA_MEMBER_FUN#", posStart);
        pos2 = temp.find("#LOOPEND_MEMBER_FUN#", pos1);
        
        if (pos1 != -1 && pos2 != -1)
        {
            len = pos2 - pos1 + EString("#LOOPEND_MEMBER_FUN#").size();
            EString loopStr = temp.subStr(pos1, len);

            loopStr.replace("#LOOPSTA_MEMBER_FUN#", "");
            loopStr.replace("#LOOPEND_MEMBER_FUN#", "");

            EString contentTemp;
            for (int i = 0; i < c->functionList.size(); i++)
            {
                CppInfo::FunctionPtr fun = c->functionList[i];
                if (fun->name.left(3) != "ui_")
                {
                    continue;
                }
                this->replaceTemplateMemberFun(loopStr, c, fun, contentTemp);
            }
            temp.replace(pos1, len, contentTemp.data());
        }
    }

    {
        //handle member vars
        size_t pos1 = 0;
        size_t pos2 = 0;
        size_t len = 0;
        size_t posStart = 0;

        pos1 = temp.find("#LOOPSTA_MEMBER_VAR#", posStart);
        pos2 = temp.find("#LOOPEND_MEMBER_VAR#", pos1);

        if (pos1 != -1 && pos2 != -1)
        {
            len = pos2 - pos1 + EString("#LOOPEND_MEMBER_VAR#").size();
            EString loopStr = temp.subStr(pos1, len);

            loopStr.replace("#LOOPSTA_MEMBER_VAR#", "");
            loopStr.replace("#LOOPEND_MEMBER_VAR#", "");

            EString contentTemp;
            for (int i = 0; i < c->variableList.size(); i++)
            {
                CppInfo::VariablePtr var = c->variableList[i];
                if (var->name.left(3) != "ui_")
                {
                    continue;
                }
                this->replaceTemplateMemberVar(loopStr, c, var, contentTemp);
            }
            temp.replace(pos1, len, contentTemp.data());
        }

        content += temp;
    }
}

void AutogenCodeGenerator::replaceTemplateConstructFunction(const EString& templateStr, CppInfo::ClassPtr c, EString& content)
{
    EString temp = templateStr;
    temp.replace("#EItemName#", c->name.data());
    content += temp;
}

void AutogenCodeGenerator::replaceTemplateFactoryFunction(const EString& templateStr, CppInfo::ClassPtr c, EString& content)
{
    EString temp = templateStr;
    temp.replace("#EItemName#", c->name.data());
    content += temp;
}

void AutogenCodeGenerator::replaceTemplateRegistPluginFunction(const EString& templateStr, CppInfo::ClassPtr c, EString& content)
{
    EString temp = templateStr;
    temp.replace("#EItemName#", c->name.data());
    temp.replace("#EItemDescription#", c->description.data());
    content += temp;
}

void AutogenCodeGenerator::replaceTemplateEnd(const EString& templateStr, CppInfo::ClassPtr c, EString& content)
{
    EString temp = templateStr;
    temp.replace("#EItemName#", c->name.data());
    content += temp;
}

void AutogenCodeGenerator::fillTemplateStr_cpp()
{
    const char* strData1 = R"(
#include <DefineCommon.h>
#include <EItem.h>
#include <EItemMeta.h>
#include <#EItemName#.h>
#include <Autogen/#EItemName#_autogen.h>
    )";

    // const char* strData2 = "\
// class #EItemName#_MemberFun_#MemberFunName# : public EItemMetaFunction\
// {\
// virtual void callInternal(intptr_t itemPtr, ... )\
// ";

// {\n\
// va_list args;\n\

             // va_start(args, itemPtr);\n\


             // EVariant* valueReturn = va_arg(args, EVariant*);
// #LOOPSTA#    EVariant* value_#parameterName# = va_arg(args, EVariant*);
// #LOOPEND#

             // #EItemName#* itemSubPtr = (#EItemName#*)this->getOwner();
                 // itemSubPtr->#MemberFunName#(
// #LOOPSTA#                  value_#parameterName#->to_#parameterType#(),#LOOPEND#
                      // );

             // va_end(args);
         // }
// };

    const char* strData2 = R"(
/**class member functions*/
class #EItemName#_MemberFun_#MemberFunName# : public EItemMetaFunction
{
         virtual void callInternal(intptr_t itemPtr, ... )
         {
             va_list args;
             va_start(args, itemPtr);

             EVariant* valueReturn = va_arg(args, EVariant*);
            #LOOPSTA#    
            EVariant* value_#parameterName# = va_arg(args, EVariant*);
            #LOOPEND#

             #EItemName#* itemSubPtr = (#EItemName#*)this->getOwner();
                 itemSubPtr->#MemberFunName#(
                    #LOOPSTA#                  
                        value_#parameterName#->to_#parameterType#(),#LOOPEND#
                      );

             va_end(args);
         }
};
    )";

    const char* strData3 = R"(
/**class set property functions*/
void #EItemName#_OnSet_#MemberVarName#(intptr_t owner, const EVariant& value)
{
    #EItemName#* itemSubPtr = (#EItemName#*)owner;
    itemSubPtr->#MemberVarName# = value.to_#MemberVarType#();
    itemSubPtr->OnSet_#MemberVarName#(value.to_#MemberVarType#());
}
)";

    const char* strData3_3 = R"(
/**class set property functions*/
void #EItemName#_OnSet_#MemberVarName#(intptr_t owner, const EVariant& value)
{
    #EItemName#* itemSubPtr = (#EItemName#*)owner;
    itemSubPtr->#MemberVarName# = value.to_#MemberVarType#();
}
)";

    const char* strData4 = R"(
/**class get property functions*/
void #EItemName#_OnGet_#MemberVarName#(intptr_t owner, EVariant& value)
{
    #EItemName#* itemSubPtr = (#EItemName#*)owner;
    itemSubPtr->OnGet_#MemberVarName#(value.to_#MemberVarType#());
}
)";

    const char* strData4_4 = R"(
/**class get property functions*/
void #EItemName#_OnGet_#MemberVarName#(intptr_t owner, EVariant& value)
{
    #EItemName#* itemSubPtr = (#EItemName#*)owner;
    value = itemSubPtr->#MemberVarName#;
}
)";

    const char* strData5 = R"(
/**Function that create EItemMetaPtr*/
EItemMetaPtr #EItemName#_createMeta(EItem* itemPtr)
{
    //ELOG_DEBUG("----------");
    #EItemName#* itemSubPtr = (#EItemName#*)itemPtr;
    EItemMetaPtr metaPtr = NewSmartPtr(EItemMeta)();
    metaPtr->setClassName("#EItemName#");
    metaPtr->setClassDescription("#EItemDescription#");

    #LOOPSTA_MEMBER_FUN#
    /**add class member function to metaPtr: #MemberFunName#*/
    {
        EItemMetaFunctionPtr fun = NewSmartPtr(#EItemName#_MemberFun_#MemberFunName#)();
        fun->setName("#MemberFunName#");
        fun->setFunType(EItemMetaFunction::FunType::CLASS_MEMBER);
        fun->setOwner((intptr_t)itemPtr);
        fun->setGroupName("#MemberFunGroupName#");

        {
            EItemMetaPropertyPtr prop = NewSmartPtr(EItemMetaProperty)();
            prop->name = "returnValue";
            prop->typeName = "#MemberFunReturnType#";
            fun->setReturnProperty(prop);
        }

        #LOOPSTA#
        {
            EItemMetaPropertyPtr prop = NewSmartPtr(EItemMetaProperty)();
            prop->name = "#parameterName#";
            prop->typeName = "#parameterType#";
            fun->addProperty(prop);
        }
        #LOOPEND#

        metaPtr->addFunction(fun);
    }
    #LOOPEND_MEMBER_FUN#

    /**add properties to metaPtr*/
    #LOOPSTA_MEMBER_VAR#
    /**property #MemberVarName#*/
    {
        EItemMetaPropertyPtr prop = NewSmartPtr(EItemMetaProperty)();
        prop->name = "#MemberVarName#";
        prop->typeName = "#MemberVarType#";
        prop->value = itemSubPtr->#MemberVarName#;
        prop->m_owner = (intptr_t)itemSubPtr;
        prop->m_funSetProperty = #EItemName#_OnSet_#MemberVarName#;
        prop->m_funGetProperty = #EItemName#_OnGet_#MemberVarName#;
        prop->groupName = "#MemberVarGroupName#";

        metaPtr->addProperty(prop);
    }
    #LOOPEND_MEMBER_VAR#

    /**property ui_testDouble
    {
        tempValue = itemSubPtr->ui_testDouble;

        EItemMetaPropertyPtr prop = NewSmartPtr(EItemMetaProperty)();
        prop->name = "testDouble";
        prop->typeName = "Double";
        prop->value = tempValue;
        prop->maxValue = itemSubPtr->ui_testDouble_max;
        prop->minValue = itemSubPtr->ui_testDouble_min;
        prop->m_owner = (intptr_t)itemSubPtr;
        prop->m_funSetProperty = EItemTestAutogen_Fun_OnSet_testDouble;
        prop->m_funGetProperty = EItemTestAutogen_Fun_OnGet_testDouble;

        metaPtr->addProperty(prop);
    }*/

    return metaPtr;
}
)";

    const char* strData6 = R"(
/**Called by #EItemName#'s construct function*/
void #EItemName#_construct_autogen(EItem* itemPtr)
{
    itemPtr->setFunCreateMeta(#EItemName#_createMeta);
}
    )";

    const char* strData7 = R"(

/**class factory functions*/
class #EItemName#_factoryFun : public EItemMetaFunction
{
    virtual void callInternal(intptr_t itemPtr, ... )
    {
        va_list args;
        va_start(args, itemPtr);
        EVariant* valueReturn = va_arg(args, EVariant*);

        #EItemName#* newPtr = new #EItemName#();
        *valueReturn = (intptr_t)newPtr;

        va_end(args);
    }
};
    )";

    const char* strData8 = R"(
void #EItemName#_registToPlugin(const EItemPtr& rootType)
{
    EItemPtr type(new EItem);
    type->setName("#EItemName#");
    type->setDescription("#EItemDescription#");

    EItemMetaFunctionPtr fun = NewSmartPtr(#EItemName#_factoryFun)();

    fun->setName("#EItemName#_Fun_factory");
    fun->setFunType(EItemMetaFunction::FunType::CONSTRUCTOR);

    type->getOrCreatMeta()->addFunction(fun);
    
    rootType->addChild(type);
}

// EItemMetaFunctionPtr #EItemName#Autogen_getFactoryFun()
// {
    // EItemMetaFunctionPtr fun = NewSmartPtr(EItemTestAutogen_Fun_factory)();

    // fun->setName("EItemTestAutogen_Fun_factory");
    // fun->setFunType(EItemMetaFunction::FunType::CONSTRUCTOR);


    // return fun;
// }
    )";


    const char* strData9 = R"(
#endif // #EItemName#_H
    )";
    // const char* strData2 = "\
// [>*class member functions<]\n\
// class #EItemName#_MemberFun_#MemberFunName# : public EItemMetaFunction\n\
        // ";
    m_templateInclude = strData1;
    m_templateMemberFunction = strData2;
    m_templateMemberValueSetFun = strData3;
    m_templateMemberValueSetFun_default = strData3_3;
    m_templateMemberValueGetFun = strData4;
    m_templateMemberValueGetFun_default = strData4_4;
    m_templateCreateMetaFunction = strData5;
    m_templateConstructFunction = strData6;
    m_templateFactoryFunction = strData7;
    m_templateRegistPluginFunction = strData8;
    m_templateEnd = strData9;
}

void AutogenCodeGenerator::classToFile_h(CppInfo::ClassPtr c, const EString& fileName)
{
    std::ofstream file(fileName.data());
    if (!file)
    {
        ELOG_ERROR("Failed to open file %s", fileName.data());
        return;
    }

    EString content;
    this->replaceTemplateInclude(this->m_templateInclude_h, c, content);
    this->replaceTemplateInclude(this->m_templateConstructFunction_h, c, content);
    this->replaceTemplateInclude(this->m_templateRegistPluginFunction_h, c, content);
    this->replaceTemplateInclude(this->m_templateEnd_h, c, content);

    file << content.data() << std::endl;

    file.close();
}

void AutogenCodeGenerator::fillTemplateStr_h()
{
    const char* strData1 = R"(
#ifndef #EItemName#_H
#define #EItemName#_H

#include <DefineCommon.h>
#include <EItem.h>
    )";

    const char* strData2 = R"(
/**Called by #EItemName#'s construct function*/
void #EItemName#_construct_autogen(EItem* itemPtr);
    )";
    const char* strData3 = R"(
void #EItemName#_registToPlugin(const EItemPtr& rootType);
)";
    const char* strData4 = R"(
#endif // #EItemName#_H
    )";

    m_templateInclude_h = strData1;
    m_templateConstructFunction_h = strData2;
    m_templateRegistPluginFunction_h = strData3;
    m_templateEnd_h = strData4;
}
